﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#if WINDOWS_PHONE
using Microsoft.Xna.Framework.Input.Touch;
#endif
#if WINDOWS
using Microsoft.Xna.Framework.Storage;
#endif
using Microsoft.Xna.Framework.Media;
using Neat;
using Neat.MenuSystem;
using Neat.EasyMenus;
using Neat.GUI;
using Neat.Mathematics;
using Neat.Graphics;
using System.IO;
namespace RiverRaidX
{
    public partial class RiverRaidGame : Screen
    {
        #region Draw
        void ProcessShaders()
        {
            var effect = game.GetEffect("ColorFilter");
            effect.CurrentTechnique = effect.Techniques["ColorTint"];

            if (blinkFrame > 0)
            {
                blinkFrame--;
                if (blinkFrame % blinkPeriod == 0)
                {
                    effect.Parameters["color"].SetValue(GraphicsHelper.GetRandomColor().ToVector4());
                    toggleBlink = !toggleBlink;
                }
                if (toggleBlink)
                {
                    game.UseEffect(effect);
                }
            }
            else if (state == GameStates.DeathAnimation)
            {
                effect.Parameters["color"].SetValue(Color.OrangeRed.ToVector4());
                game.UseEffect(effect);
            }
            else if (fuel < maxFuel * 0.25f)
            {
                siren.X += 0.075f;
                if (siren.X > 1.5f) siren.X = -1.5f;

                effect.Parameters["color"].SetValue(siren);
                effect.CurrentTechnique = effect.Techniques["ColorBalance"];
                game.UseEffect(effect);
            }
        }
        float half;


        public override void Render(GameTime gameTime)
        {
            if (!NoPlayer && !NoPostFx)
            {
                game.SpriteBatch.End();
                game.GraphicsDevice.SetRenderTarget(target);
                game.GraphicsDevice.Clear(game.GameBackgroundColor);
                game.SpriteBatch.Begin();
            }

            ProcessShaders();


            ////////////////////
            // Draw Exterior
            ////////////////////
            float currentY = 0;
            if (checkpoints.Count > 0)
                currentY = checkpoints[0];
            var checkPointNo = 0;
            grassColor = grassColors[startingLevel % 2];

            for (int i = 1; i < outerWalls.Count; i++)
            {
                game.SpriteBatch.Draw(
                    game.GetTexture("solid"),
                    new Rectangle(0, (int)(outerWalls[i].Y + yOffset),
                        (int)(outerWalls[i - 1].X), (int)(outerWalls[i - 1].Y - outerWalls[i].Y)), grassColor);
                game.SpriteBatch.Draw(
                   game.GetTexture("solid"),
                   new Rectangle((int)(game.GameWidth - outerWalls[i - 1].X), (int)(outerWalls[i].Y + yOffset),
                       (int)(outerWalls[i - 1].X), (int)(outerWalls[i - 1].Y - outerWalls[i].Y)), grassColor);
                if (currentY >= outerWalls[i - 1].Y && checkPointNo + 1 < checkpoints.Count)
                {
                    currentY = checkpoints[++checkPointNo];
                    grassColor = grassColors[(startingLevel + checkPointNo) % 2];
                }
            }

            ////////////////////
            // Draw Interior
            ////////////////////
            currentY = 0;
            checkPointNo = 0;
            if (checkpoints.Count > 0)
                currentY = checkpoints[0];
            grassColor = grassColors[startingLevel % 2];

            for (int i = 1; i < innerWalls.Count; i++)
            {
                if (currentY >= innerWalls[i - 1].Y && checkPointNo + 1 < checkpoints.Count)
                {
                    currentY = checkpoints[++checkPointNo];
                    grassColor = grassColors[(startingLevel + checkPointNo) % 2];
                }
                game.SpriteBatch.Draw(
                    game.GetTexture("solid"),
                    new Rectangle((int)(half - innerWalls[i - 1].X), (int)(innerWalls[i].Y + yOffset),
                        (int)(2 * innerWalls[i - 1].X), (int)(innerWalls[i - 1].Y - innerWalls[i].Y)), grassColor);
            }

            if (state != GameStates.DeathAnimation) //1
                game.RestartBatch();

            ////////////////////
            // Draw Checkpoints
            ////////////////////
            var road = game.GetTexture("road");
            var bridge = game.GetTexture("bridge");
            var roadOffsetY = 0;// (bridge.Height - road.Height) / -2.0f;

            for (int i = 0; i < checkpoints.Count; i++)
            {
                game.SpriteBatch.Draw(road, new Rectangle(0, (int)(checkpoints[i] + roadOffsetY + yOffset) - 1,
                    (int)(game.GameWidth - bridge.Width * scale.X) / 2 + 2, (int)(bridge.Height * scale.Y) + 2), Color.White);
                game.SpriteBatch.Draw(road, new Rectangle(1 + (int)(bridge.Width * scale.X) + (int)(game.GameWidth - bridge.Width * scale.X) / 2, (int)(checkpoints[i] + roadOffsetY + yOffset) - 1,
                    (int)(game.GameWidth - bridge.Width * scale.X) / 2 + 5, (int)(bridge.Height * scale.Y) + 2), Color.White);
            }

            ////////////////////
            // Draw Entities
            ////////////////////
            for (int i = 0; i < entities.Count; i++)
            {
                var item = entities[i];
                game.SpriteBatch.Draw(game.GetTexture(item.TextureName),
                    GeometryHelper.Vectors2Rectangle(new Vector2(item.Position.X, item.Position.Y + yOffset),
                    item.Size), null, Color.White, 0, Vector2.Zero, item.Flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0);
            }

            ////////////////////
            // Draw Dead Entities
            ////////////////////
            if (deadEntities.Count > 0)
            {
                var rippleEffect = game.GetEffect("ripple");
                game.UseEffect(rippleEffect);
                var explosion = game.GetSlice("explosion");

                for (int i = 0; i < deadEntities.Count; i++)
                {
                    var item = deadEntities[i];
                    item.ZombieTimer++;
                    rippleEffect.Parameters["amplitude"].SetValue(1.0f);
                    rippleEffect.Parameters["phase"].SetValue(MathHelper.ToRadians(Frame + item.ZombieTimer));
                    var rect = GeometryHelper.Vectors2Rectangle(new Vector2(item.Position.X, item.Position.Y + yOffset), item.Size);
                    game.SpriteBatch.Draw(game.GetTexture(item.TextureName),
                        rect, null, GraphicsHelper.GetColorWithAlpha(Color.White,  1.0f - item.ZombieTimer / explosionLife), 0, Vector2.Zero, item.Flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, 0);
                }
                game.UseEffect(rippleEffect);
                for (int i = 0; i < deadEntities.Count; i++)
                {
                    var item = deadEntities[i];
                    var rect = GeometryHelper.Vectors2Rectangle(new Vector2(item.Position.X, item.Position.Y + yOffset), item.Size);
                    game.SpriteBatch.Draw(explosion.Texture, rect, explosion.Crop, Color.White);

                    if (item.ZombieTimer > explosionLife)
                    {
                        deadEntities.RemoveAt(i);
                    }
                }
                game.RestartBatch();
            }

            ////////////////////
            // Draw Rocket
            ////////////////////
            if (rocketLaunched)
            {
                game.SpriteBatch.Draw(
                    game.GetTexture("solid"),
                    new Rectangle((int)((pSize.X - rocketSize.X) / 2 + pPos.X), (int)(rocketY + yOffset), (int)rocketSize.X, (int)rocketSize.Y), Color.Yellow);
            }

            ////////////////////
            // Draw Player
            ////////////////////
            if (!NoPlayer)
            {
                if (state == GameStates.DeathAnimation) //1
                {
                    var rippleEffect = game.GetEffect("ripple");
                    game.UseEffect(rippleEffect);

                    rippleEffect.Parameters["amplitude"].SetValue(1.0f);
                    rippleEffect.Parameters["phase"].SetValue(MathHelper.ToRadians(deathFrame));
                    rippleEffect.Parameters["tint"].SetValue(new Vector4(1.0f, 1.0f, 1.0f, MathHelper.Clamp((float)(deathFrame) / (float)(deathTime * 2), 0, 1)));
                }

                game.SpriteBatch.Draw(
                    (pxVel == 0 ? game.GetTexture("raider") : game.GetTexture("raider_mv")),
                    new Rectangle((int)pPos.X, (int)(pPos.Y + yOffset), (int)(pxVel == 0 ? stillPlayerWidth : movingPlayerWidth), (int)pSize.Y), null, Color.White, 0, Vector2.Zero,
                    (pxVel < 0 ? SpriteEffects.FlipHorizontally : SpriteEffects.None), 0);

                if (state == GameStates.DeathAnimation) //1
                {
                    var rippleEffect = game.GetEffect("ripple");
                    game.UseEffect(rippleEffect);
                    var explosion = game.GetSlice("explosion");
                    rippleEffect.Parameters["tint"].SetValue(new Vector4(1.0f, 1.0f, 1.0f, 1.0f));
                    var rect = new Rectangle((int)pPos.X, (int)(pPos.Y + yOffset), (int)(pxVel == 0 ? stillPlayerWidth : movingPlayerWidth), (int)pSize.Y);
                    game.SpriteBatch.Draw(explosion.Texture, rect, explosion.Crop, Color.White);
                }
            }

            if (!NoPlayer && !NoPostFx)
            {
                var fsfx = game.GetEffect("fullscreen");
                fsfx.Parameters["noise"].SetValue((float)game.RandomGenerator.NextDouble());
                fsfx.Parameters["doNoise"].SetValue(!gameTime.IsRunningSlowly);
                var screenSize = new Vector2(game.GameWidth, game.GameHeight);
                fsfx.Parameters["rocketPos"].SetValue(rocketPos / screenSize);
                fsfx.Parameters["lastRocketPos"].SetValue(lastRocketPos / screenSize);
                fsfx.Parameters["rocketSize"].SetValue(rocketLaunched ? rocketSize / screenSize : Vector2.Zero);
                game.SpriteBatch.End();
                game.GraphicsDevice.SetRenderTarget(game.DefaultTarget);
                game.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, fsfx);
                game.SpriteBatch.Draw(target, new Rectangle(0,0,game.OutputResolution.X, game.OutputResolution.Y), Color.White);
            }

            game.RestartBatch();
            base.Render(gameTime);
        }
        #endregion
    }
}